一. 继承的相关概念
1. 继承的意义
在面向对象语言中, 类就是模板, 通过模板可以创造出各种对象. 有些对象有一些共同的属性和方法, 如果在每个类定义里面都写一遍, 就很麻烦. 可以通过继承超类, 然后再完善自身的类, 达到一样的目的而不用写那么多代码.
2. 继承的语法
1 | class 子类 extends 父类名 |
- 父类, 超类: 通常指直接上级
- 基类: 通常指包括直接上级在内的 “上级的上级”
3. 基础的特点
- 子类自动拥有父类声明为 public 和 protectedd 的成员
- 在子类里面是没办法访问父类中私有成员的
- 可以看成是子类里面有这个私有成员, 但是没有访问权限. 因为在子类里面, 可以调用父类的方法输出父类的私有成员
二. 继承条件下类的访问权限
- public: 外界可以自由访问
- private: 外界不可访问
- protected: 子类中可以访问
- default: 同一个包中的类可以访问
三. 构造函数的调用顺序
- 因为继承之后, 有可能有些属性在子类中的构造函数中没有被初始化, 所以需要调用父类的构造函数来初始化.
- 虽然没有调用父类的构造函数, 但是会隐式的调用父类中无参的构造函数.
- 如果父类中没有无参的构造函数, 在子类中又没有调用其他构造函数, 那么就会出错. (跟 C++ 一样)
- 在子类的构造函数中调用父类的构造函数, 必须是第一句就调用. (我认为是因为有些东西是在父类中初始化的)
四. 不可修改的类
这样的类就是不可修改的类, 它不能被继承
1 | final class 类名{ |
五. 当直接输出一个对象引用时会发生什么?
当调用
1 | System.out.println(new A()); |
首先会调用
1 | public void println(Object x); |
还有调用
1 | public static String valueOf(Object obj); |
以及
1 | public String toString() { |
最后输出: inherit.A@7852e922
六. 子类和父类方法之间的关系
- 扩充: 增加父类中没有的方法
- 覆盖/重写: 修改父类中的方法(方法名, 参数, 返回值都相同)
- 重载: 与父类方法的方法名相同, 但参数不同.
七. 重写 toString 方法
- 在 + 运算中, 任何一个对象与 String 对象连接时, 都会隐式调用 toString 方法
八. 方法覆盖的要点
- 形式一定要完全相同, 否则就变成重载了
- 可以通过 super 调用超类中被覆盖的方法
九. 方法覆盖的语法规则
- 覆盖方法的允许访问范围不能小于原方法
- 覆盖方法所抛出的异常不能比原方法更多
- 声明为 final 的方法不允许覆盖
- 不能覆盖静态方法